/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.lerning.edu.manage.util;

import com.lerning.edu.beans.SysReport;
import com.lerning.edu.beans.SysRole;
import com.lerning.edu.commons.util.SpringContextHolder;
import com.lerning.edu.beans.SysResource;
import com.lerning.edu.beans.SysUser;
import com.lerning.edu.commons.util.CacheUtils;
import com.lerning.edu.manage.security.SystemAuthorizingRealm.Principal;
import com.lerning.edu.services.SysReportService;
import com.lerning.edu.services.SysResourceService;
import com.lerning.edu.services.SysRoleService;
import com.lerning.edu.services.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import java.util.ArrayList;
import java.util.List;

/**
 * 用户工具类
 * @author ThinkGem
 * @version 2013-12-05
 */
public class UserUtils {

	private static SysUserService userService = SpringContextHolder.getBean(SysUserService.class);
	private static SysRoleService roleService = SpringContextHolder.getBean(SysRoleService.class);
	private static SysResourceService resourceService = SpringContextHolder.getBean(SysResourceService.class);
	private static SysReportService reportService = SpringContextHolder.getBean(SysReportService.class);

	public static final String USER_CACHE = "userCache";
	public static final String USER_CACHE_ID_ = "id_";
	public static final String USER_CACHE_LOGIN_NAME_ = "ln";
//	public static final String USER_CACHE_LIST_BY_OFFICE_ID_ = "oid_";

	public static final String CACHE_ROLE_LIST = "roleList";
	public static final String CACHE_MENU_LIST = "menuList";
	public static final String CACHE_REPORT_LIST = "reportList";
//	public static final String CACHE_AREA_LIST = "areaList";
//	public static final String CACHE_OFFICE_LIST = "officeList";
//	public static final String CACHE_OFFICE_ALL_LIST = "officeAllList";

	/**
	 * 根据ID获取用户
	 * @param id
	 * @return 取不到返回null
	 */
	public static SysUser get(Long id){
//		CacheUtils.remove(USER_CACHE, USER_CACHE_ID_ + id);
		SysUser user = (SysUser)CacheUtils.get(USER_CACHE, USER_CACHE_ID_ + id);
		if (user ==  null){
			user = userService.queryById(id);
			if (user == null){
				return null;
			}
			user.setRoleList(roleService.queryList(new SysRole(user)));
			CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
			CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getAccount(), user);
		}
		return user;
	}

	/**
	 * 清除当前用户缓存
	 */
	public static void clearCache(){
		removeCache(CACHE_ROLE_LIST);
		removeCache(CACHE_MENU_LIST);
//		removeCache(CACHE_AREA_LIST);
//		removeCache(CACHE_OFFICE_LIST);
//		removeCache(CACHE_OFFICE_ALL_LIST);
		UserUtils.clearCache(getUser());
	}

	/**
	 * 清除指定用户缓存
	 * @param user
	 */
	public static void clearCache(SysUser user){
		CacheUtils.remove(USER_CACHE, USER_CACHE_ID_ + user.getId());
		CacheUtils.remove(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getAccount());
	}

	/**
	 * 获取当前用户
	 * @return 取不到返回 new User()
	 */
	public static SysUser getUser(){
		Principal principal = getPrincipal();
		if (principal!=null){
			SysUser user = get(principal.getId());
			if (user != null){
				return user;
			}
			return new SysUser();
		}
		// 如果没有登录，则返回实例化空的User对象。
		return new SysUser();
	}

	/**
	 * 获取当前用户角色列表
	 * @return
	 */
	public static List<SysRole> getRoleList(){
		@SuppressWarnings("unchecked")
		List<SysRole> roleList = (List<SysRole>)getCache(CACHE_ROLE_LIST);
		if (roleList == null){
			SysUser user = getUser();
			if (user.isAdmin()){
				roleList = roleService.findAllList(new SysRole());
			}else{
				SysRole role = new SysRole();
				role.setSysUser(user);
				roleList = roleService.queryList(role);
			}
			putCache(CACHE_ROLE_LIST, roleList);
		}
		return roleList;
	}

	/**
	 * 获取当前用户授权菜单
	 * @return
	 */
	public static List<SysResource> getMenuList(){
//		removeCache(CACHE_MENU_LIST);
		List<SysResource> menuList = (List<SysResource>)getCache(CACHE_MENU_LIST);
		if (menuList == null){
			SysUser user = getUser();
			if (user.isAdmin()){
				menuList = resourceService.findAllList(new SysResource());
			}else{
				SysResource m = new SysResource();
				m.setUserId(user.getId());
				menuList = resourceService.findByUserId(m);
			}
			putCache(CACHE_MENU_LIST, menuList);
		}
		return menuList;
	}

	/**
	 * 获取当前用户授权报表
	 * @return
	 */
	public static List<SysReport> getReportList(){
//		removeCache(CACHE_MENU_LIST);
		@SuppressWarnings("unchecked")
		List<SysReport> reportList = (List<SysReport>)getCache(CACHE_REPORT_LIST);
		if (reportList == null){
			SysUser user = getUser();
			if (user.isAdmin()){
				reportList = reportService.queryListByReport(new SysReport());
			}else{
				SysReport p = new SysReport();
				p.setUserId(user.getId());
				reportList = reportService.findByUserId(p);
			}
			putCache(CACHE_REPORT_LIST, reportList);
		}
		return reportList;
	}

	/**
	 * 获取子菜单
	 * @return
	 */
	public static List<SysResource> getSubMenuList(Long id){
		List<SysResource> menuList = (List<SysResource>)getCache(CACHE_MENU_LIST);
		if (menuList == null){
			menuList = getMenuList();
			putCache(CACHE_MENU_LIST, menuList);
		}
		List<SysResource> subMenuList = new ArrayList<SysResource>();
		for(SysResource menu : menuList) {
			if(menu.getParentId() == id ) {
				subMenuList.add(menu);
			}
		}
		return subMenuList;
	}

	/**
	 * 获取授权主要对象
	 */
	public static Subject getSubject(){
		return SecurityUtils.getSubject();
	}

	/**
	 * 获取当前登录者对象
	 */
	public static Principal getPrincipal(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Principal principal = (Principal)subject.getPrincipal();
			if (principal != null){
				return principal;
			}
//			subject.logout();
		}catch (UnavailableSecurityManagerException e) {

		}catch (InvalidSessionException e){

		}
		return null;
	}

	public static Session getSession(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Session session = subject.getSession(false);
			if (session == null){
				session = subject.getSession();
			}
			if (session != null){
				return session;
			}
//			subject.logout();
		}catch (InvalidSessionException e){

		}
		return null;
	}

	// ============== User Cache ==============

	public static Object getCache(String key) {
		return getCache(key, null);
	}

	public static Object getCache(String key, Object defaultValue) {
//		Object obj = getCacheMap().get(key);
		Object obj = getSession().getAttribute(key);
		return obj==null?defaultValue:obj;
	}

	public static void putCache(String key, Object value) {
//		getCacheMap().put(key, value);
		getSession().setAttribute(key, value);
	}

	public static void removeCache(String key) {
//		getCacheMap().remove(key);
		getSession().removeAttribute(key);
	}
}
